import * as cc from "cc";
import { Loger } from '../../../../framework/loger/Loger';
import SceneMgr from "../../../../framework/scene/SceneMgr";
import { TweenEasing } from "../../../../framework/utils/AnimationUtils";
import MathUtils from "../../../../framework/utils/MathUtils";
import { FlyIconData } from "../model/ModelFlyIcon";
import VCFlyIcon from "../vc/VCFlyIcon";
import { ViewBase } from './../../../../framework/view/ViewBase';
import { ViewLayer } from './../../../../framework/view/ViewConsts';

const { ccclass, property, menu } = cc._decorator;
@ccclass("ViewFlyIcon")
@menu("GameView/ViewFlyIcon")
export default class ViewFlyIcon extends ViewBase {

    protected static prefabUrl: string = "game/prefab/mvc/fly_icon/FlyIcon";
    public static className: string = "ViewFlyIcon"
    protected vc: VCFlyIcon = null;

    @property({ type: cc.Node, tooltip: "要飞的节点原件" })
    icon: cc.Node = null;
    //生命周期：onInit(加载时只调一次)==>onOpen(每次showui时)==>onShow()==>onStart()==>onHide()==>onClose()
    /**只会在首次加载时调用一次，可以用于获取节点，绑定事件 */
    protected onInit() {
        super.onInit();
        this.icon.active = false;
    }

    /**每次打开UI前，onStart前,每次呼出前赋值传参的时候用 */
    protected onOpen() {
        super.onOpen();
    }

    /**开始动画播完 onShow之后*/
    protected onStart() {
        super.onStart();
    }

    /**关闭动画结束后 */
    protected onClose() {
        super.onClose();
    }

    /**update生命周期 */
    protected onUpdate(dt) {
    }

    async flyIcon(data: FlyIconData, callback?: () => void) {
        let root = data.iconRoot || SceneMgr.getInstance().getUIRoot(data.iconRootLayer || ViewLayer.Layer_Hud_Effect);
        if (!root) {
            Loger.error(`==flyIcon root is null==`)
            callback();
            return;
        }
        //初始化数据
        data.randomRadius = data.randomRadius || 100;
        data.flyCount = data.flyCount || 10;
        data.iconScaleFrom = data.iconScaleFrom || 1;
        data.iconScaleTo = data.iconScaleTo || 1;
        let iconNode = data.iconNode;
        if (!data.iconNode) {
            iconNode = this.icon;
            if (!!data.iconName) {
                const comSprite = iconNode.getComponent(cc.Sprite);
                const path = data.iconPath || `game/prefab/mvc/fly_icon/texture`;
                //Loger.log("fly path="+`${path}/${data.iconName}/spriteFrame`)
                comSprite.spriteFrame = await this.getSpriteFrame(`${path}/${data.iconName}`);
            } else {
                Loger.error(`==iconName is null`)
                callback();
                return;

            }
        }
        const iconUiTrans = iconNode.getComponent(cc.UITransform);
        const rootUiTrans = root.getComponent(cc.UITransform);
        data.fromWorldPos = data.fromWorldPos || iconUiTrans.convertToWorldSpaceAR(cc.Vec3.ZERO);
        let endPos = rootUiTrans.convertToNodeSpaceAR(data.targetWorldPos);
        let endCount = 0;

        const posArr = MathUtils.genPositionByCountInCircle(data.fromWorldPos, data.randomRadius, data.flyCount)
        for (let i = 0; i < posArr.length; i++) {
            const startPos = rootUiTrans.convertToNodeSpaceAR(posArr[i]);
            let node = cc.instantiate(iconNode)
            let sprite = node.getComponent(cc.Sprite)
            if (sprite) {
                sprite.spriteFrame.addRef();
            }
            node.active = true;
            node.setParent(root)
            node.setScale(cc.v3(0, 0.0))
            node.position = startPos;
            const comOpacity = (node.getComponent(cc.UIOpacity) || node.addComponent(cc.UIOpacity))
            comOpacity.opacity = 0;
            cc.tween(comOpacity)
                .to(0.2, { opacity: 255 })
                .start()
            cc.tween(node)
                .to(0.2, { scale: cc.v3(data.iconScaleFrom, data.iconScaleFrom, 1) },
                    { easing: TweenEasing.smooth })
                .delay(i * 0.08)
                .parallel(
                    cc.tween().to(0.8, { position: endPos }, { easing: TweenEasing.smooth }),
                    cc.tween().to(0.8, { scale: cc.v3(data.iconScaleTo, data.iconScaleTo, 1) }, { easing: TweenEasing.smooth })
                )
                .call(() => {
                    let sprite = node.getComponent(cc.Sprite)
                    if (sprite) {
                        sprite.spriteFrame.decRef();
                    }
                    node.destroy();
                    endCount++;
                    if (endCount >= data.flyCount) {
                        callback && callback();
                    }
                })
                .start();
        }
    }
}